package com.jlcloud.core.tool.utils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>身份证工具类</p>
 *
 * @author By: JlCloud <br>
 * @Package: com.jlcloud.core.tool.utils <br>
 * @CreateTime: 2024-12-11 15:39 <br>
 * @Copyright: 2021 www.jilianjituan.com Inc. All rights reserved. <br>
 * @Caution 注意：本内容仅限于冀联人力集团内部传阅，禁止外泄以及用于其他的商业目的 <br>
 */

public class IdCardUtil {


	private static final Pattern ID_NUM_PATTERN = Pattern.compile("^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$");

	private static final DateTimeFormatter BIRTHDAY_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");


	/**
	 * 解析身份证号
	 *
	 * @param idNum
	 * @return 1 男；0 女
	 */
	public static Map<String, Object> resolveIdNum(String idNum) {
		Matcher matcher = ID_NUM_PATTERN.matcher(idNum);
		if (!matcher.matches()) {
			throw new RuntimeException("无效的身份证号");
		}
		// 第7到14位为出生年月日
		String birthdayStr = idNum.substring(6, 14);
		// 第17位区别性别，奇数为男，偶数为女
		String genderStr = idNum.substring(16, 17);
		// 年龄计算
		int age = getAge(idNum);
		LocalDate birthday = LocalDate.parse(birthdayStr, BIRTHDAY_FORMATTER);
		int gender = Integer.parseInt(genderStr);
		Map<String, Object> resMap = new HashMap<>();
		resMap.put("birthday", birthday);
		resMap.put("gender", gender & 1);
		resMap.put("age", age);
		return resMap;
	}

	/**
	 * 根据身份证号获取年龄
	 *
	 * @param idNum
	 * @return
	 */
	public static int getAge(String idNum) {
		Calendar cal = Calendar.getInstance();
		int yearNow = cal.get(Calendar.YEAR);
		int monthNow = cal.get(Calendar.MONTH) + 1;
		int dayNow = cal.get(Calendar.DATE);
		int age = 0;
		int year = Integer.valueOf(idNum.substring(6, 10));
		int month = Integer.valueOf(idNum.substring(10, 12));
		int day = Integer.valueOf(idNum.substring(12, 14));

		if ((month < monthNow) || (month == monthNow && day <= dayNow)) {
			age = yearNow - year;
		} else {
			age = yearNow - year - 1;
		}
		return age;
	}

}
